package com.cn.por.auto.factory;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.cn.por.auto.dto.*;
import com.cn.por.auto.entity.TableDetiles;
import com.cn.por.auto.enums.FunctionName;
import com.cn.por.auto.enums.ModelType;
import com.cn.por.util.freemarker.StringFormaterUtil;
import org.apache.ibatis.type.JdbcType;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 生成数据模型工厂类,通过传入不同的数据类型生成数据模型对象,一个模型对象对应一个要
 * 生成的文件,
 * 现在的问题是入参的转换抽象到哪一层?
 * CodeFactory 进行数据模型的组合
 * HsaDataModelFactory 进行数据模型对象的生成.
 *
 * CodeFactory工厂类,接收的是 hsa入参, 需要返回的两个大类是前端vue2(此方法抽象)
 * 和后端spring+mybatis-plus 代码(此方法抽象)
 * hsa框架对应的是 dao dto do controller service serviceImpl bo boImpl spring+mybatis-plus框架
 *    前端 js index add modify preview   vue2框架
 */
public class SpringMybatisPlusDataModelFactory implements DataModelGenaFactory{
    /**
     * 产出的数据模型
     */
    private ModelParam modelParam;

    /**
     * 无参构造器
     */
    public SpringMybatisPlusDataModelFactory() {
    }

    public SpringMybatisPlusDataModelFactory(ModelParam modelParam){
        this.modelParam = modelParam;
    }

    @Override
    public DataModel getDataModel(ModelType dataModelType) {
        switch (dataModelType){
            case DTO:
                return this.getDTO();
            case DO:
                return this.getDO();
            case CONVERTER:
                return this.getConverter();
            case SERVICE:
                return this.getService();
            case BO:
                return this.getBO();
            case CONTROLLER:
                return this.getController();
            case SERVICE_IMPL:
                return this.getServiceImp();
            case BO_IMPL:
                return this.getBOImp();
            case DAO:
                return this.getDAO();
            case MAPPER:
                return this.getMapper();
            default: return null;
        }
    }



    private DataModel getMapper(){
        MapperDataModel dataModel = new MapperDataModel();
        dataModel.setFtlName("basic/mapper.ftl");
        /**
         * entityName
         */
        String meta = StringFormaterUtil.columnToProperty(this.modelParam.isPrefix()? this.modelParam.getTableName().substring(this.modelParam.getTableName().indexOf("_")+1):this.modelParam.getTableName() );
        String entityName = meta  +"Mapper";
        dataModel.setFileName(entityName +".xml");
        dataModel.setZipDir("sql/"+StringFormaterUtil.lowerCaptureName(meta)+"/" +dataModel.getFileName());

        dataModel.setBasePackage(this.modelParam.getBasePackage());
        dataModel.setEntityName(meta+"DO");
        dataModel.setNamespace(this.modelParam.getBasePackage()+".dao."+meta+"DAO");

        List<MapperRelation> mapperRelationList = new ArrayList<MapperRelation>();
        for (TableDetiles column : modelParam.getTableColumn()) {
            MapperRelation mapperRe = new MapperRelation();
            mapperRe.setColumn(column.getColumnName().toUpperCase());
            mapperRe.setProperty(
                    StringFormaterUtil.lowerCaptureName(StringFormaterUtil.columnToProperty(column.getColumnName())));
            mapperRelationList.add(mapperRe);
        }
        dataModel.setMapperRelations(mapperRelationList);
        /**
         * 表主键
         */
        dataModel.setPrimaryKey(modelParam.getPrimaryKey());
        dataModel.setTableName(this.modelParam.getTableName());
        CommonComponent selectPage = new CommonComponent();
        selectPage.setParameterType(dataModel.getBasePackage() + ".entity." + dataModel.getEntityName());
        List<MapperRelation> conditions = new ArrayList<MapperRelation>();
        for (TableDetiles condition : modelParam.getConditionColumn()) {
            for (MapperRelation mr : dataModel.getMapperRelations()) {
                if (condition.getColumnName().toLowerCase().equals(mr.getColumn().toLowerCase())) {
                    MapperRelation m1 = new MapperRelation();
                    m1.setColumn(mr.getColumn());
                    m1.setProperty(mr.getProperty());
                    conditions.add(m1);
                }
            }
        }
        selectPage.setConditions(conditions);
        dataModel.setSelectPage(selectPage);
        return dataModel;
    }

    private DataModel getDAO(){
        DataModel dataModel = new DataModel();
        dataModel.setFtlName("basic/interfaceDesc.ftl");
        /**
         * entityName
         */
        String meta = StringFormaterUtil.columnToProperty(this.modelParam.isPrefix()? this.modelParam.getTableName().substring(this.modelParam.getTableName().indexOf("_")+1):this.modelParam.getTableName() );
        String entityName = meta  +"DAO";
        dataModel.setFileName(entityName +".java");
        dataModel.setZipDir(this.modelParam.getBasePackage().replace(".", "/")+"/dao/"+dataModel.getFileName());

        /**
         * 当前时间
         */
        dataModel.setCurrentDate(DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN));

        /**
         * 包名
         */
        dataModel.setPackageName(
                this.modelParam.getBasePackage()
                        + ".dao"
        );
        /**
         * 导包
         */
        List<String> importPackage  = new ArrayList<String>();
        importPackage.add(this.modelParam.getBasePackage()+".entity."+meta+"DO");
        importPackage.add("com.baomidou.mybatisplus.core.mapper.BaseMapper");
        importPackage.add("com.baomidou.mybatisplus.extension.plugins.pagination.Page");
        importPackage.add("org.apache.ibatis.annotations.Param");
        dataModel.setImportPackage(importPackage);
        /**
         * 类名称,注释,继承
         */
        dataModel.setClassName(entityName);
        dataModel.setClassDesc(this.modelParam.getTableComment()+"dao接口");
        dataModel.setUserName(this.modelParam.getUserName());
        dataModel.setBaseInterfaceName("BaseMapper<"+meta+"DO>");

        /**
         * 方法
         */
        List<FunctionMessage> functionMessages= new ArrayList<>();
        //新增
        FunctionMessage add = new FunctionMessage();
        add.setFunctionName(FunctionName.customPageList.name());
        add.setResultType("Page<"+meta+"DO>");
        add.setFuncDesc("自定义分页方法");
        List<FunctionMessage> paramterAdd = new ArrayList<>();
        FunctionMessage paramAdd = new FunctionMessage();
        paramAdd.setParamterType("@Param(\"page\") Page<"+ meta+"DO>");
        paramAdd.setParamterName("page");
        paramterAdd.add(paramAdd);
        FunctionMessage paramAdd1 = new FunctionMessage();
        paramAdd1.setParamterType("@Param(\"param\") "+ meta+"DO");
        paramAdd1.setParamterName("param");
        paramterAdd.add(paramAdd1);
        add.setParamterList(paramterAdd);
        functionMessages.add(add);
        dataModel.setFunctionMsgs(functionMessages);

        return dataModel;
    }

    private DataModel getBOImp(){
        BoImplDataModel dataModel = new BoImplDataModel();
        dataModel.setFtlName("basic/boImpl.ftl");
        /**
         * entityName
         */
        String meta = StringFormaterUtil.columnToProperty(this.modelParam.isPrefix()? this.modelParam.getTableName().substring(this.modelParam.getTableName().indexOf("_")+1):this.modelParam.getTableName() );
        String entityName = meta  +"BOImpl";
        dataModel.setFileName(entityName +".java");
        dataModel.setZipDir(this.modelParam.getBasePackage().replace(".", "/")+"/bo/impl/"+dataModel.getFileName());

        /**
         * 当前时间
         */
        dataModel.setCurrentDate(DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN));

        /**
         * 包名
         */
        dataModel.setPackageName(
                this.modelParam.getBasePackage()
                        + ".bo.impl"
        );
        /**
         * 导包
         */
        List<String> importPackage  = new ArrayList<String>();
        importPackage.add("cn.hsa.base.web.vo.PageFactory");
        importPackage.add("cn.hsa.base.web.vo.PageResultData");
        importPackage.add(this.modelParam.getBasePackage()+".dao."+meta+"DAO");
        importPackage.add(this.modelParam.getBasePackage()+".bo."+meta+"BO");
        importPackage.add(this.modelParam.getBasePackage()+".entity."+meta+"DO");
        importPackage.add(this.modelParam.getBasePackage()+".dto."+meta+"DTO");
        importPackage.add(this.modelParam.getBasePackage()+".dto."+meta+"DTOConverter");
        importPackage.add("com.baomidou.mybatisplus.extension.service.impl.ServiceImpl");
        importPackage.add("com.baomidou.mybatisplus.core.conditions.query.QueryWrapper");
        importPackage.add("com.baomidou.mybatisplus.extension.plugins.pagination.Page");
        importPackage.add("org.springframework.stereotype.Service");
        importPackage.add("org.springframework.beans.factory.annotation.Autowired");
        importPackage.add("org.springframework.util.StringUtils");
        importPackage.add("java.util.ArrayList");
        importPackage.add("java.util.List");
        dataModel.setImportPackage(importPackage);
        /**
         * 类名称,注释,继承
         */
        dataModel.setClassName(entityName);
        dataModel.setClassDesc(this.modelParam.getTableComment()+"实现层");
        dataModel.setUserName(this.modelParam.getUserName());
        dataModel.setBaseInterfaceName(meta+"BO");
        dataModel.setExtendsClass("ServiceImpl<"+meta+"DAO, "+meta+"DO>");
        dataModel.setAnnotations(Arrays.asList("Service"));
        dataModel.setInjectClass(meta+"DAO");
        dataModel.setPrimaryKey(this.modelParam.getPrimaryKey());
        dataModel.setPrimaryKeyProperty(StringFormaterUtil.columnToProperty(this.modelParam.getPrimaryKey()));


        /**
         * 添加属性
         */
        List<MapperRelation> propertys = new ArrayList<>();
        MapperRelation property = new MapperRelation();
        property.setAnnotation("Autowired");
        property.setPropertyType(meta+"DAO");
        property.setProperty(StringFormaterUtil.lowerCaptureName(meta+"DAO"));
        MapperRelation property1 = new MapperRelation();
        property1.setAnnotation("Autowired");
        property1.setPropertyType(meta+"DTOConverter");
        property1.setProperty(StringFormaterUtil.lowerCaptureName(meta+"DTOConverter"));
        propertys.add(property1);
        propertys.add(property);
        dataModel.setMapperRelations(propertys);
        dataModel.setMeta(meta);

        /**
         * 添加动态查询条件
         */
        List<MapperRelation> condition = new ArrayList<>();
        for (TableDetiles column: this.modelParam.getConditionColumn()){
            MapperRelation item = new MapperRelation();
            item.setProperty(StringFormaterUtil.columnToProperty(column.getColumnName()));
            item.setColumn(column.getColumnName());
            item.setPropertyType(column.getDataType());
            condition.add(item);
        }
        dataModel.setContitions(condition);

        return dataModel;
    }
    private DataModel getServiceImp(){
        EntityDataModel dataModel = new EntityDataModel();
        dataModel.setFtlName("basic/entity.ftl");
        /**
         * entityName
         */
        String meta = StringFormaterUtil.columnToProperty(this.modelParam.isPrefix()? this.modelParam.getTableName().substring(this.modelParam.getTableName().indexOf("_")+1):this.modelParam.getTableName() );
        String entityName = meta  +"ServiceImpl";
        dataModel.setFileName(entityName +".java");
        dataModel.setZipDir(this.modelParam.getBasePackage().replace(".", "/")+"/service/impl/"+dataModel.getFileName());

        /**
         * 当前时间
         */
        dataModel.setCurrentDate(DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN));

        /**
         * 包名
         */
        dataModel.setPackageName(
                this.modelParam.getBasePackage()
                        + ".service.impl"
        );
        /**
         * 导包
         */
        List<String> importPackage  = new ArrayList<String>();
        importPackage.add("cn.hsa.base.web.vo.PageResultData");
        importPackage.add("org.springframework.beans.factory.annotation.Autowired");
        importPackage.add("org.springframework.stereotype.Service");
        importPackage.add(this.modelParam.getBasePackage()+".bo."+meta+"BO");
        importPackage.add(this.modelParam.getBasePackage()+".dto."+meta+"DTO");
        importPackage.add(this.modelParam.getBasePackage()+".service."+meta+"Service");
        dataModel.setImportPackage(importPackage);
        /**
         * 类名称,注释,继承
         */
        dataModel.setClassName(entityName);
        dataModel.setClassDesc(this.modelParam.getTableComment()+"业务层");
        dataModel.setUserName(this.modelParam.getUserName());
        dataModel.setBaseInterfaceName(meta+"Service");
        List<String> classAnnotataion = new ArrayList<>();
        classAnnotataion.add("Service");
        dataModel.setAnnotations(classAnnotataion);
        dataModel.setInjectClass(meta+"BO");
        /**
         * 添加属性
         */
        List<MapperRelation> propertys = new ArrayList<>();
        MapperRelation property = new MapperRelation();
        property.setAnnotation("Autowired");
        property.setPropertyType(meta+"BO");
        property.setProperty(StringFormaterUtil.lowerCaptureName(meta)+"BO");
        propertys.add(property);
        dataModel.setMapperRelations(propertys);

        /**
         * 方法
         */
        List<FunctionMessage> functionMessages= new ArrayList<>();
        //新增
        List<String> functionAnn = Arrays.asList("Override");
        FunctionMessage add = new FunctionMessage();
        add.setFunctionName(FunctionName.add.name());
        add.setResultType(meta+"DTO");
        add.setFuncDesc("新增");
        add.setAnnotationList(functionAnn);
        List<FunctionMessage> paramterAdd = new ArrayList<>();
        FunctionMessage paramAdd = new FunctionMessage();
        paramAdd.setParamterType(meta+"DTO");
        paramAdd.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DTO");
        paramterAdd.add(paramAdd);
        add.setParamterList(paramterAdd);
        functionMessages.add(add);
        //修改
        FunctionMessage update = new FunctionMessage();
        update.setFunctionName(FunctionName.update.name());
        update.setResultType(meta+"DTO");
        update.setFuncDesc("更新");
        update.setAnnotationList(functionAnn);
        List<FunctionMessage> paramterUpdate = new ArrayList<>();
        FunctionMessage paramUpdate = new FunctionMessage();
        paramUpdate.setParamterType(meta+"DTO");
        paramUpdate.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DTO");
        paramterUpdate.add(paramUpdate);
        update.setParamterList(paramterUpdate);
        functionMessages.add(update);
        //作废
        FunctionMessage delete = new FunctionMessage();
        delete.setFunctionName(FunctionName.delete.name());
        delete.setResultType("Boolean");
        delete.setFuncDesc("作废");
        delete.setAnnotationList(functionAnn);
        List<FunctionMessage> paramterDelete = new ArrayList<>();
        FunctionMessage paramDelete = new FunctionMessage();
        paramDelete.setParamterType("String");
        paramDelete.setParamterName("id");
        paramterDelete.add(paramDelete);
        delete.setParamterList(paramterDelete);
        functionMessages.add(delete);

        //查询单条数据
        FunctionMessage get = new FunctionMessage();
        get.setFunctionName(FunctionName.get.name());
        get.setResultType(meta+"DTO");
        get.setFuncDesc("查询单条数据");
        get.setAnnotationList(functionAnn);
        List<FunctionMessage> paramterGet = new ArrayList<>();
        FunctionMessage paramGet = new FunctionMessage();
        paramGet.setParamterType("String");
        paramGet.setParamterName("id");
        paramterGet.add(paramGet);
        get.setParamterList(paramterGet);
        functionMessages.add(get);

        //分页获取数据
        FunctionMessage getPage = new FunctionMessage();
        getPage.setFunctionName(FunctionName.getPage.name());
        getPage.setResultType("PageResultData<"+meta+"DTO>");
        getPage.setFuncDesc("分页获取数据");
        getPage.setAnnotationList(functionAnn);
        List<FunctionMessage> paramterGetPage = new ArrayList<>();
        FunctionMessage paramGetPage = new FunctionMessage();
        paramGetPage.setParamterType("int");
        paramGetPage.setParamterName("pageNo");
        paramterGetPage.add(paramGetPage);

        FunctionMessage paramGetPage2 = new FunctionMessage();
        paramGetPage2.setParamterType("int");
        paramGetPage2.setParamterName("pageSize");
        paramterGetPage.add(paramGetPage2);

        FunctionMessage paramGetPage3 = new FunctionMessage();
        paramGetPage3.setParamterType(meta+"DTO");
        paramGetPage3.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DTO");
        paramterGetPage.add(paramGetPage3);
        getPage.setParamterList(paramterGetPage);
        functionMessages.add(getPage);

        dataModel.setFunctionMsgs(functionMessages);

        return dataModel;
    }

    private DataModel getController(){
        InterfaceDataModel dataModel = new InterfaceDataModel();
        dataModel.setFtlName("basic/controller.ftl");
        /**
         * entityName
         */
        String meta = StringFormaterUtil.columnToProperty(this.modelParam.isPrefix()? this.modelParam.getTableName().substring(this.modelParam.getTableName().indexOf("_")+1):this.modelParam.getTableName() );
        String entityName = meta  +"Controller";
        dataModel.setFileName(entityName +".java");
        dataModel.setZipDir(this.modelParam.getBasePackage().replace(".", "/")+"/controller/"+dataModel.getFileName());

        /**
         * 当前时间
         */
        dataModel.setCurrentDate(DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN));

        /**
         * 方法后缀名
         */
        dataModel.setSuffixName(meta);
        /**
         * 包名
         */
        dataModel.setPackageName(
                this.modelParam.getBasePackage()
                        + ".controller"
        );
        /**
         * 导包
         */
        List<String> importPackage  = new ArrayList<String>();
        importPackage.add(this.modelParam.getBasePackage()+".dto."+meta+"DTO");
        importPackage.add(this.modelParam.getBasePackage()+".entity."+meta+"DO");
        importPackage.add("cn.hsa.base.web.vo.PageResultData");
        importPackage.add("cn.hsa.base.web.BaseController");
        importPackage.add("cn.hsa.base.web.vo.WrapperResponse");
        importPackage.add(this.modelParam.getBasePackage()+".service."+meta+"Service");
        importPackage.add("org.springframework.beans.factory.annotation.Autowired");
        importPackage.add("org.springframework.web.bind.annotation.*");
        importPackage.add("io.swagger.annotations.Api");
        importPackage.add("io.swagger.annotations.ApiOperation");
        dataModel.setImportPackage(importPackage);
        /**
         * 类名称,注释,继承,调用链中下个类
         */
        dataModel.setClassName(entityName);
        dataModel.setClassDesc(this.modelParam.getTableComment()+"控制器");
        dataModel.setUserName(this.modelParam.getUserName());
        dataModel.setExtendsClass("BaseController");
        dataModel.setInjectClass(meta+"Service");

        /**
         * 类上添加注解
         */
        List<String> annotations = new ArrayList<>();
        annotations.add("RestController");
        annotations.add("RequestMapping(\"/web/"+this.modelParam.getBasePackage().substring(this.modelParam.getBasePackage().lastIndexOf(".")+1) +"/"+StringFormaterUtil.lowerCaptureName(meta) +"\")");
        annotations.add("Api(tags = \""+ this.modelParam.getTableComment()+"\")");
        dataModel.setAnnotations(annotations);

        /**
         * 添加属性
         */
        List<MapperRelation> propertys = new ArrayList<>();
        MapperRelation property = new MapperRelation();
        property.setAnnotation("Autowired");
        property.setPropertyType(meta+"Service");
        property.setProperty(StringFormaterUtil.lowerCaptureName(meta)+"Service");
        propertys.add(property);
        dataModel.setMapperRelations(propertys);

        /**
         * 方法
         */
        List<FunctionMessage> functionMessages= new ArrayList<>();
        //新增
        FunctionMessage add = new FunctionMessage();

        List<String> annotationAdd = new ArrayList<>();
        annotationAdd.add("PostMapping(\"/add\")");
        annotationAdd.add("ApiOperation(value = \"新增\")");
        add.setAnnotationList(annotationAdd);

        add.setFunctionName(FunctionName.add.name());
        add.setResultType(meta+"DTO");
        add.setFuncDesc("新增");
        List<FunctionMessage> paramterAdd = new ArrayList<>();
        FunctionMessage paramAdd = new FunctionMessage();
        paramAdd.setParamterType("@RequestBody "+meta+"DTO");
        paramAdd.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DTO");
        paramterAdd.add(paramAdd);
        add.setParamterList(paramterAdd);
        functionMessages.add(add);
        //修改
        FunctionMessage update = new FunctionMessage();
        update.setFunctionName(FunctionName.update.name());
        update.setResultType(meta+"DTO");

        List<String> annotationUpdate = new ArrayList<>();
        annotationUpdate.add("PostMapping(\"/edit\")");
        annotationUpdate.add("ApiOperation(value = \"修改\")");
        update.setAnnotationList(annotationUpdate);

        update.setFuncDesc("更新");
        List<FunctionMessage> paramterUpdate = new ArrayList<>();
        FunctionMessage paramUpdate = new FunctionMessage();
        paramUpdate.setParamterType("@RequestBody "+meta+"DTO");
        paramUpdate.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DTO");
        paramterUpdate.add(paramUpdate);
        update.setParamterList(paramterUpdate);
        functionMessages.add(update);
        //作废
        FunctionMessage delete = new FunctionMessage();
        delete.setFunctionName(FunctionName.delete.name());
        delete.setResultType("Boolean");
        delete.setFuncDesc("作废");
        List<String> annotationDelete = new ArrayList<>();
        annotationDelete.add("GetMapping(\"/delete\")");
        annotationDelete.add("ApiOperation(value = \"作废\")");
        delete.setAnnotationList(annotationDelete);

        List<FunctionMessage> paramterDelete = new ArrayList<>();
        FunctionMessage paramDelete = new FunctionMessage();
        paramDelete.setParamterType("@RequestParam String");
        paramDelete.setParamterName("id");
        paramterDelete.add(paramDelete);
        delete.setParamterList(paramterDelete);
        functionMessages.add(delete);

        //查询单条数据
        FunctionMessage get = new FunctionMessage();
        get.setFunctionName(FunctionName.get.name());
        get.setResultType(meta+"DTO");
        get.setFuncDesc("查询单条数据");
        List<String> annotationGet = new ArrayList<>();
        annotationGet.add("GetMapping(\"/item\")");
        annotationGet.add("ApiOperation(value = \"获取\")");
        get.setAnnotationList(annotationGet);

        List<FunctionMessage> paramterGet = new ArrayList<>();
        FunctionMessage paramGet = new FunctionMessage();
        paramGet.setParamterType("String");
        paramGet.setParamterName("id");
        paramterGet.add(paramGet);
        get.setParamterList(paramterGet);
        functionMessages.add(get);

        //分页获取数据
        FunctionMessage getPage = new FunctionMessage();
        getPage.setFunctionName(FunctionName.getPage.name());
        getPage.setResultType("PageResultData<"+meta+"DTO>");

        List<String> annotationGetPage = new ArrayList<>();
        annotationGetPage.add("PostMapping(\"/page\")");
        annotationGetPage.add("ApiOperation(value = \"获取分页\")");
        getPage.setAnnotationList(annotationGetPage);

        getPage.setFuncDesc("分页获取数据");
        List<FunctionMessage> paramterGetPage = new ArrayList<>();
        FunctionMessage paramGetPage = new FunctionMessage();
        paramGetPage.setParamterType("@RequestParam Integer");
        paramGetPage.setParamterName("pageNo");
        paramterGetPage.add(paramGetPage);

        FunctionMessage paramGetPage2 = new FunctionMessage();
        paramGetPage2.setParamterType("@RequestParam Integer");
        paramGetPage2.setParamterName("pageSize");
        paramterGetPage.add(paramGetPage2);

        FunctionMessage paramGetPage3 = new FunctionMessage();
        paramGetPage3.setParamterType("@RequestBody "+meta+"DTO");
        paramGetPage3.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DTO");
        paramterGetPage.add(paramGetPage3);



        getPage.setParamterList(paramterGetPage);
        functionMessages.add(getPage);

        dataModel.setFunctionMsgs(functionMessages);

        return dataModel;
    }
    private DataModel getBO(){
        DataModel dataModel = new DataModel();
        dataModel.setFtlName("basic/interfaceDesc.ftl");
        /**
         * entityName
         */
        String meta = StringFormaterUtil.columnToProperty(this.modelParam.isPrefix()? this.modelParam.getTableName().substring(this.modelParam.getTableName().indexOf("_")+1):this.modelParam.getTableName() );
        String entityName = meta  +"BO";
        dataModel.setFileName(entityName +".java");
        dataModel.setZipDir(this.modelParam.getBasePackage().replace(".", "/")+"/bo/"+dataModel.getFileName());

        /**
         * 当前时间
         */
        dataModel.setCurrentDate(DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN));

        /**
         * 包名
         */
        dataModel.setPackageName(
                this.modelParam.getBasePackage()
                        + ".bo"
        );
        /**
         * 导包
         */
        List<String> importPackage  = new ArrayList<String>();
        importPackage.add(this.modelParam.getBasePackage()+".dto."+meta+"DTO");
        importPackage.add(this.modelParam.getBasePackage()+".entity."+meta+"DO");
        importPackage.add("cn.hsa.base.web.vo.PageResultData");
        importPackage.add("com.baomidou.mybatisplus.extension.service.IService");
        dataModel.setImportPackage(importPackage);
        /**
         * 类名称,注释,继承
         */
        dataModel.setClassName(entityName);
        dataModel.setClassDesc(this.modelParam.getTableComment()+"BO");
        dataModel.setUserName(this.modelParam.getUserName());
        dataModel.setBaseInterfaceName("IService<"+meta+"DO>");

        /**
         * 方法
         */
        List<FunctionMessage> functionMessages= new ArrayList<>();
        //新增
        FunctionMessage add = new FunctionMessage();
        add.setFunctionName(FunctionName.add.name());
        add.setResultType(meta+"DTO");
        add.setFuncDesc("新增");
        List<FunctionMessage> paramterAdd = new ArrayList<>();
        FunctionMessage paramAdd = new FunctionMessage();
        paramAdd.setParamterType(meta+"DTO");
        paramAdd.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DTO");
        paramterAdd.add(paramAdd);
        add.setParamterList(paramterAdd);
        functionMessages.add(add);
        //修改
        FunctionMessage update = new FunctionMessage();
        update.setFunctionName(FunctionName.update.name());
        update.setResultType(meta+"DTO");
        update.setFuncDesc("更新");
        List<FunctionMessage> paramterUpdate = new ArrayList<>();
        FunctionMessage paramUpdate = new FunctionMessage();
        paramUpdate.setParamterType(meta+"DTO");
        paramUpdate.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DTO");
        paramterUpdate.add(paramUpdate);
        update.setParamterList(paramterUpdate);
        functionMessages.add(update);
        //作废
        FunctionMessage delete = new FunctionMessage();
        delete.setFunctionName(FunctionName.delete.name());
        delete.setResultType("Boolean");
        delete.setFuncDesc("作废");
        List<FunctionMessage> paramterDelete = new ArrayList<>();
        FunctionMessage paramDelete = new FunctionMessage();
        paramDelete.setParamterType("String");
        paramDelete.setParamterName("id");
        paramterDelete.add(paramDelete);
        delete.setParamterList(paramterDelete);
        functionMessages.add(delete);

        //查询单条数据
        FunctionMessage get = new FunctionMessage();
        get.setFunctionName(FunctionName.get.name());
        get.setResultType(meta+"DTO");
        get.setFuncDesc("查询单条数据");
        List<FunctionMessage> paramterGet = new ArrayList<>();
        FunctionMessage paramGet = new FunctionMessage();
        paramGet.setParamterType("String");
        paramGet.setParamterName("id");
        paramterGet.add(paramGet);
        get.setParamterList(paramterGet);
        functionMessages.add(get);

        //分页获取数据
        FunctionMessage getPage = new FunctionMessage();
        getPage.setFunctionName(FunctionName.getPage.name());
        getPage.setResultType("PageResultData<"+meta+"DTO>");
        getPage.setFuncDesc("分页获取数据");
        List<FunctionMessage> paramterGetPage = new ArrayList<>();
        FunctionMessage paramGetPage = new FunctionMessage();
        paramGetPage.setParamterType("int");
        paramGetPage.setParamterName("pageNo");
        paramterGetPage.add(paramGetPage);

        FunctionMessage paramGetPage2 = new FunctionMessage();
        paramGetPage2.setParamterType("int");
        paramGetPage2.setParamterName("pageSize");
        paramterGetPage.add(paramGetPage2);

        FunctionMessage paramGetPage3 = new FunctionMessage();
        paramGetPage3.setParamterType(meta+"DTO");
        paramGetPage3.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DTO");
        paramterGetPage.add(paramGetPage3);
        getPage.setParamterList(paramterGetPage);
        functionMessages.add(getPage);

        dataModel.setFunctionMsgs(functionMessages);

        return dataModel;
    }
    private DataModel getService(){
        DataModel dataModel = new DataModel();
        dataModel.setFtlName("basic/interfaceDesc.ftl");
        /**
         * entityName
         */
        String meta = StringFormaterUtil.columnToProperty(this.modelParam.isPrefix()? this.modelParam.getTableName().substring(this.modelParam.getTableName().indexOf("_")+1):this.modelParam.getTableName() );
        String entityName = meta  +"Service";
        dataModel.setFileName(entityName +".java");
        dataModel.setZipDir(this.modelParam.getBasePackage().replace(".", "/")+"/service/"+dataModel.getFileName());

        /**
         * 当前时间
         */
        dataModel.setCurrentDate(DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN));

        /**
         * 包名
         */
        dataModel.setPackageName(
                this.modelParam.getBasePackage()
                        + ".service"
        );
        /**
         * 导包
         */
        List<String> importPackage  = new ArrayList<String>();
        importPackage.add(this.modelParam.getBasePackage()+".dto."+meta+"DTO");
        importPackage.add("cn.hsa.base.web.vo.PageResultData");
        dataModel.setImportPackage(importPackage);
        /**
         * 类名称,注释
         */
        dataModel.setClassName(entityName);
        dataModel.setClassDesc(this.modelParam.getTableComment()+"Service");
        dataModel.setUserName(this.modelParam.getUserName());

        /**
         * 方法
         */
        List<FunctionMessage> functionMessages= new ArrayList<>();
        //新增
        FunctionMessage add = new FunctionMessage();
        add.setFunctionName(FunctionName.add.name());
        add.setResultType(meta+"DTO");
        add.setFuncDesc("新增");
        List<FunctionMessage> paramterAdd = new ArrayList<>();
        FunctionMessage paramAdd = new FunctionMessage();
        paramAdd.setParamterType(meta+"DTO");
        paramAdd.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DTO");
        paramterAdd.add(paramAdd);
        add.setParamterList(paramterAdd);
        functionMessages.add(add);
        //修改
        FunctionMessage update = new FunctionMessage();
        update.setFunctionName(FunctionName.update.name());
        update.setResultType(meta+"DTO");
        update.setFuncDesc("更新");
        List<FunctionMessage> paramterUpdate = new ArrayList<>();
        FunctionMessage paramUpdate = new FunctionMessage();
        paramUpdate.setParamterType(meta+"DTO");
        paramUpdate.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DTO");
        paramterUpdate.add(paramUpdate);
        update.setParamterList(paramterUpdate);
        functionMessages.add(update);
        //作废
        FunctionMessage delete = new FunctionMessage();
        delete.setFunctionName(FunctionName.delete.name());
        delete.setResultType("Boolean");
        delete.setFuncDesc("作废");
        List<FunctionMessage> paramterDelete = new ArrayList<>();
        FunctionMessage paramDelete = new FunctionMessage();
        paramDelete.setParamterType("String");
        paramDelete.setParamterName("id");
        paramterDelete.add(paramDelete);
        delete.setParamterList(paramterDelete);
        functionMessages.add(delete);

        //查询单条数据
        FunctionMessage get = new FunctionMessage();
        get.setFunctionName(FunctionName.get.name());
        get.setResultType(meta+"DTO");
        get.setFuncDesc("查询单条数据");
        List<FunctionMessage> paramterGet = new ArrayList<>();
        FunctionMessage paramGet = new FunctionMessage();
        paramGet.setParamterType("String");
        paramGet.setParamterName("id");
        paramterGet.add(paramGet);
        get.setParamterList(paramterGet);
        functionMessages.add(get);

        //分页获取数据
        FunctionMessage getPage = new FunctionMessage();
        getPage.setFunctionName(FunctionName.getPage.name());
        getPage.setResultType("PageResultData<"+meta+"DTO>");
        getPage.setFuncDesc("分页获取数据");
        List<FunctionMessage> paramterGetPage = new ArrayList<>();
        FunctionMessage paramGetPage = new FunctionMessage();
        paramGetPage.setParamterType("int");
        paramGetPage.setParamterName("pageNo");
        paramterGetPage.add(paramGetPage);

        FunctionMessage paramGetPage2 = new FunctionMessage();
        paramGetPage2.setParamterType("int");
        paramGetPage2.setParamterName("pageSize");
        paramterGetPage.add(paramGetPage2);

        FunctionMessage paramGetPage3 = new FunctionMessage();
        paramGetPage3.setParamterType(meta+"DTO");
        paramGetPage3.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DTO");
        paramterGetPage.add(paramGetPage3);
        getPage.setParamterList(paramterGetPage);


        functionMessages.add(getPage);

        dataModel.setFunctionMsgs(functionMessages);

        return dataModel;
    }
    private DataModel getConverter(){
        DataModel dataModel = new DataModel();
        dataModel.setFtlName("basic/converter.ftl");
        /**
         * entityName
         */
        String meta = StringFormaterUtil.columnToProperty(this.modelParam.isPrefix()? this.modelParam.getTableName().substring(this.modelParam.getTableName().indexOf("_")+1):this.modelParam.getTableName() );
        String entityName = meta  +"DTOConverter";
        dataModel.setFileName(entityName +".java");
        dataModel.setZipDir(this.modelParam.getBasePackage().replace(".", "/")+"/dto/"+dataModel.getFileName());

        /**
         * 当前时间
         */
        dataModel.setCurrentDate(DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN));

        /**
         * 包名
         */
        dataModel.setPackageName(
                this.modelParam.getBasePackage()
                        + ".dto"
        );
        /**
         * 导包
         */
        List<String> importPackage  = new ArrayList<String>();
        importPackage.add(this.modelParam.getBasePackage()+".entity."+meta+"DO");
        importPackage.add("org.springframework.beans.BeanUtils");
        importPackage.add("org.springframework.stereotype.Component");
        dataModel.setImportPackage(importPackage);
        /**
         * 类名称,注释
         */
        dataModel.setClassName(entityName);
        dataModel.setClassDesc(this.modelParam.getTableComment()+"Converter");
        dataModel.setUserName(this.modelParam.getUserName());
        /**
         * 类上添加注解
         */
        List<String> annotations = new ArrayList<>();
        annotations.add("Component");
        dataModel.setAnnotations(annotations);

        /**
         * 方法
         */
        List<FunctionMessage> functionMessages= new ArrayList<>();
        FunctionMessage toDO = new FunctionMessage();
        toDO.setFunctionName("convertTo"+meta+"DO");
        toDO.setResultType(meta+"DO");
        toDO.setFuncDesc("DTO-->DO");
        toDO.setParamterType(meta+"DTO");
        toDO.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DTO");
        //日期类型转换
        List<String> toDTOCodes = new ArrayList<>();
        List<String> toDoCodes = new ArrayList<>();
        boolean hsaDate = false;
        for (TableDetiles cols : modelParam.getTableColumn()) {
            if("datetime".equals(cols.getColumnType())){
                String str = StringFormaterUtil.captureName(StringFormaterUtil.columnToProperty(cols.getColumnName()));
                toDoCodes.add("if(StrUtil.isNotEmpty("+StringFormaterUtil.lowerCaptureName(meta)+"DTO.get"+str+"())){\n" +
                        "            "+StringFormaterUtil.lowerCaptureName(meta)+"DO.set"+str+"(DateUtil.parse("+StringFormaterUtil.lowerCaptureName(meta)+"DTO.get"+str+"(), DatePattern.NORM_DATETIME_PATTERN));\n" +
                        "        }");
                toDTOCodes.add("if(null!="+StringFormaterUtil.lowerCaptureName(meta)+"DO.get"+str+"()){\n" +
                        "            "+StringFormaterUtil.lowerCaptureName(meta)+"DTO.set"+str+"(DateUtil.format("+StringFormaterUtil.lowerCaptureName(meta)+"DO.get"+str+"(), DatePattern.NORM_DATETIME_PATTERN));\n" +
                        "        }");
                hsaDate = true;
            }
        }
        if(hsaDate){
            importPackage.add("cn.hutool.core.date.DatePattern");
            importPackage.add("cn.hutool.core.date.DateUtil");
            importPackage.add("cn.hutool.core.util.StrUtil");
        }
        toDO.setCodeBlock(toDoCodes);
        functionMessages.add(toDO);
        FunctionMessage toDTO = new FunctionMessage();
        toDTO.setFunctionName("convertTo"+meta+"DTO");
        toDTO.setResultType(meta+"DTO");
        toDTO.setFuncDesc("DO-->DTO");
        toDTO.setParamterType(meta+"DO");
        toDTO.setParamterName(StringFormaterUtil.lowerCaptureName(meta)+"DO");
        toDTO.setCodeBlock(toDTOCodes);
        functionMessages.add(toDTO);
        dataModel.setFunctionMsgs(functionMessages);

        return dataModel;
    }

    private DataModel getDO(){
        EntityDataModel dataModel = new EntityDataModel();
        dataModel.setFtlName("basic/entity.ftl");
        /**
         * entityName
         */
        String entityName = StringFormaterUtil.columnToProperty(this.modelParam.isPrefix()? this.modelParam.getTableName().substring(this.modelParam.getTableName().indexOf("_")+1):this.modelParam.getTableName() ) +"DO";
        dataModel.setFileName(entityName +".java");
        dataModel.setZipDir(this.modelParam.getBasePackage().replace(".", "/")+"/entity/"+dataModel.getFileName());

        /**
         * 当前时间
         */
        dataModel.setCurrentDate(DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN));

        /**
         * 包名
         */
        dataModel.setPackageName(
                this.modelParam.getBasePackage()
                        + ".entity"
        );

        List<String> importPackage  = new ArrayList<String>();
        importPackage.add("lombok.Data");
        importPackage.add("lombok.experimental.Accessors");
        importPackage.add("lombok.EqualsAndHashCode");
        importPackage.add("com.baomidou.mybatisplus.annotation.TableField");
        importPackage.add("com.baomidou.mybatisplus.annotation.TableId");
        importPackage.add("com.baomidou.mybatisplus.annotation.IdType");
        importPackage.add("java.io.Serializable");
        importPackage.add("com.baomidou.mybatisplus.annotation.TableName");
        /**
         * 类名称
         */
        dataModel.setClassName(entityName);
        dataModel.setBaseInterfaceName("Serializable");
        /**
         * 类上添加注解
         */
        List<String> annotations = new ArrayList<>();
        annotations.add("Data");
        annotations.add("TableName(\""+this.modelParam.getTableName()+"\")");
        annotations.add("Accessors(chain = true)");
        annotations.add("EqualsAndHashCode(callSuper = false)");
        dataModel.setAnnotations(annotations);


        /**
         * BaseResultMap 建立数据库字段与java对象映射关系
         */
        List<MapperRelation> mapperRelationList = new ArrayList<>();
        MapperRelation seri = new MapperRelation();
        seri.setPropertyType("static final long");
        seri.setProperty("serialVersionUID = 1L");
        mapperRelationList.add(seri);
        for (TableDetiles column : this.modelParam.getTableColumn()) {
            MapperRelation mapperRe = new MapperRelation();
            mapperRe.setColumn(column.getColumnName().toUpperCase());
            mapperRe.setProperty(
                    StringFormaterUtil.lowerCaptureName(StringFormaterUtil.columnToProperty(column.getColumnName())));
            for(JdbcType jdbc : JdbcType.values()) {
                if((column.getDataType().equals("int")?"integer":column.getDataType()).toLowerCase().equals(jdbc.name().toLowerCase())) {
                    mapperRe.setPropertyType(StringFormaterUtil.typeTransformer(jdbc));
                    break;
                }
            }
            /**
             * 主键的注解和其他注解区别对待
             */
            mapperRe.setColumnComment(column.getColumnComment());
            if(column.getColumnName().equals(this.modelParam.getPrimaryKey())){
                mapperRe.setAnnotation("TableId(value = \""+column.getColumnName().toUpperCase()+"\", type = IdType.ASSIGN_UUID)");
            }else{
                mapperRe.setAnnotation("TableField(\""+ column.getColumnName().toUpperCase() +"\")");
            }
            /**
             * 数据库字段类型为decimal,需要导入对应的包
             */
            if(column.getDataType().equals(JdbcType.DECIMAL.name().toLowerCase())){
                importPackage.add("java.math.BigDecimal");
            }
            if(column.getDataType().equals(JdbcType.DATE.name().toLowerCase())){
                importPackage.add("java.util.Date");
            }

            if(column.getDataType().equals("datetime")){
                importPackage.add("java.util.Date");
                mapperRe.setPropertyType("Date");
            }
            if(column.getDataType().equals("text")){
                mapperRe.setPropertyType("String");
            }
            mapperRelationList.add(mapperRe);
        }

        dataModel.setImportPackage(importPackage);
        dataModel.setMapperRelations(mapperRelationList);

        dataModel.setClassDesc(this.modelParam.getTableComment()+"DO");
        dataModel.setUserName(this.modelParam.getUserName());
        return dataModel;
    }

    /**
     * 获取Dto对象
     * @return
     */
    private DataModel getDTO(){
        EntityDataModel dataModel = new EntityDataModel();
        dataModel.setFtlName("basic/entity.ftl");
        /**
         * 当前时间
         */
        dataModel.setCurrentDate(DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN));
        /**
         * entityName
         */
        String entityName = StringFormaterUtil.columnToProperty(this.modelParam.isPrefix()? this.modelParam.getTableName().substring(this.modelParam.getTableName().indexOf("_")+1):this.modelParam.getTableName() ) +"DTO";
        dataModel.setFileName(entityName +".java");
        dataModel.setZipDir(this.modelParam.getBasePackage().replace(".", "/")+"/dto/"+dataModel.getFileName());

        /**
         * 包名1
         */
        dataModel.setPackageName(
                this.modelParam.getBasePackage()
                        + ".dto"
        );

        List<String> importPackage  = new ArrayList<String>();
        importPackage.add("lombok.Data");
        importPackage.add("java.io.Serializable");
        importPackage.add("io.swagger.annotations.ApiModelProperty");
        /**
         * 类名称
         */
        dataModel.setClassName(entityName);
        dataModel.setBaseInterfaceName("Serializable");
        /**
         * BaseResultMap 建立数据库字段与java对象映射关系
         */
        List<MapperRelation> mapperRelationList = new ArrayList<>();
        MapperRelation seri = new MapperRelation();
        seri.setPropertyType("static final long");
        seri.setProperty("serialVersionUID = 1L");
        mapperRelationList.add(seri);
        for (TableDetiles column : this.modelParam.getTableColumn()) {
            MapperRelation mapperRe = new MapperRelation();
            mapperRe.setColumn(column.getColumnName().toUpperCase());
            mapperRe.setProperty(
                    StringFormaterUtil.lowerCaptureName(StringFormaterUtil.columnToProperty(column.getColumnName())));
            for(JdbcType jdbc : JdbcType.values()) {
                if((column.getDataType().equals("int")?"integer":column.getDataType()).toLowerCase().equals(jdbc.name().toLowerCase())) {
                    mapperRe.setPropertyType(StringFormaterUtil.typeTransformer(jdbc));
                    break;
                }
            }
            mapperRe.setAnnotation("ApiModelProperty(value=\""+column.getColumnComment() + "\")");
            mapperRe.setColumnComment(column.getColumnComment());
            /**
             * 数据库字段类型为decimal,需要导入对应的包
             */
            if(column.getDataType().equals(JdbcType.DECIMAL.name().toLowerCase())){
                importPackage.add("java.math.BigDecimal");
            }
            if(column.getDataType().equals("datetime")){
                mapperRe.setPropertyType("String");
            }
            if(column.getDataType().equals("text")){
                mapperRe.setPropertyType("String");
            }
            mapperRelationList.add(mapperRe);
        }

        dataModel.setImportPackage(importPackage);
        dataModel.setMapperRelations(mapperRelationList);
        /**
         * 类上添加注解
         */
        List<String> annotations = new ArrayList<>();
        annotations.add("Data");
        dataModel.setAnnotations(annotations);
        dataModel.setClassDesc(this.modelParam.getTableComment()+"DTO");
        dataModel.setUserName(this.modelParam.getUserName());
        return dataModel;
    }
}
